package com.yanqu.road.server.manager.monopolymarket;

import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.monopolymarket.group.MonopolyMarketBackEndGroup;
import com.yanqu.road.entity.monopolymarket.group.MonopolyMarketCrossGroup;
import com.yanqu.road.logic.bussiness.monopolymarket.MonopolyMarketBussiness;
import com.yanqu.road.pb.monopolymarket.MonopolyMarketProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manger.ICrossServerGroupAccess;
import com.yanqu.road.server.manger.SystemCrossServerGroupMgr;
import com.yanqu.road.server.manger.plugin.ManagerReloadListener;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description
 * @Author cwq
 * @Data 2021/9/5 18:19
 */
public class MonopolyMarketCrossGroupMgr extends TempMgr {

    public static Logger logger = LogManager.getLogger(MonopolyMarketCrossGroupMgr.class.getName());

    /**
     * k:后台的分组id : v分组
     */
    public static Map<Long,MonopolyMarketCrossGroup> crossGroupMap = new ConcurrentHashMap<>();

//    /**
//     * k:serverId : 独立分组
//     */
//    public static Map<Long,MonopolyMarketCrossGroup> singleCrossGroupMap = new ConcurrentHashMap<>();

    private static ManagerReloadListener managerReloadListener;

    @Override
    public boolean init() throws Exception {
        crossGroupMap = MonopolyMarketBussiness.getMonopolyMarketCrossGroupMap(ConfigHelper.getInt("channelId"));
        initGroupChat();
        reload();
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        notifyReload();
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean save() {
        for (MonopolyMarketCrossGroup item : crossGroupMap.values()) {
            if (item.isUpdateOption()) {
                MonopolyMarketBussiness.updateMonopolyMarketCrossGroup(item);
            } else if (item.isInsertOption()) {
                MonopolyMarketBussiness.addMonopolyMarketCrossGroup(item);
            }
        }
        return true;
    }

    public static void addReloadListener(ManagerReloadListener reloadListener){
        managerReloadListener = reloadListener;
    }

    private static void notifyReload(){
        if(managerReloadListener != null){
            managerReloadListener.notifyReload();
        }
    }

    public static void initGroupChat(){
        SystemCrossServerGroupMgr.getAccessMap().put(eSystemId.MonopolyMarket.getValue(), new ICrossServerGroupAccess() {

            @Override
            public int getGroupIdByServerId(long serverId) {
                // NULL TODO
                return (int)(getOpenGroupByServerId(serverId).getGroupId());
            }

            @Override
            public Set<Long> getGroupServer(int groupId) {
                return new HashSet<>(getMonopolyMarketCrossGroupByGroupId(groupId).getServerList());
            }

            @Override
            public void reloadServerGroup() {

            }
        });
    }

    private static MonopolyMarketCrossGroup getMonopolyMarketCrossGroupByGroupId(long groupId){
        return crossGroupMap.get(groupId);
    }


    /**
     * 校验后台分组和跨服上的分组是否一致
     * @param channelId
     * @return 返回有变化的分组和新增分组
     */
    public static Set<MonopolyMarketCrossGroup> checkGroupChange(int channelId){
        // 与后台校验配置
        Set<MonopolyMarketCrossGroup> changeGroupSet = new HashSet<>();
        List<MonopolyMarketBackEndGroup> endGroupList =  MonopolyMarketBussiness.getMonopolyMarketBackEndGroupList(channelId);
        int now = DateHelper.getCurrentSecond();
        List<Long> backEndGroupId = new ArrayList<>();
        for (MonopolyMarketBackEndGroup endItem : endGroupList){
            backEndGroupId.add(endItem.getGroupId());
            MonopolyMarketCrossGroup crossGroup = crossGroupMap.get(endItem.getGroupId());
            if(crossGroup != null){
                // 校验区服列表是否一致
                boolean equals = equals(endItem,crossGroup);
                if(!equals){
                    logger.info("榷场分组变更。groupId:{},后台分组为:{},跨服这边的区服分组为:{}.",endItem.getGroupId(),endItem.getServerList(),crossGroup.getServerList());
                    crossGroup.setState(endItem.getState());
                    crossGroup.setServerList(endItem.getServerList());
                    crossGroup.setChangTime(DateHelper.getCurrentSecond());
                    changeGroupSet.add(crossGroup);
                }
            }else {
                crossGroup = creatMonopolyMarketCrossGroup(endItem.getGroupId(),endItem.getChannelId(),endItem.getServerList(),now,endItem.getState(),endItem.getFortressState());
                changeGroupSet.add(crossGroup);
                logger.info("榷场新增分组。分组id:{},区服:{},state:{}.fortressState:{}.",endItem.getGroupId(),endItem.getServerList(),endItem.getState(),endItem.getFortressState());
            }
        }
        for (MonopolyMarketCrossGroup item : crossGroupMap.values()){
            if(!backEndGroupId.contains(item.getGroupId()) && item.getState() == 1){
                // 后台删除正在开启的分组
                item.setState(0);
                changeGroupSet.add(item);
                logger.info("榷场删除分组。分组id:{},区服:{},state:{}.fortressState:{}.",item.getGroupId(),item.getServerList(),item.getState(),item.getFortressState());
            }
        }
        return changeGroupSet;
    }


    /**
     * 校验边关要塞的状态
     * @param channelId
     * @return 返回有变化的分组集合
     */
    public static Set<MonopolyMarketCrossGroup> checkFortressStateChange(int channelId){
        Set<MonopolyMarketCrossGroup> changeGroupSet = new HashSet<>();
        List<MonopolyMarketBackEndGroup> endGroupList =  MonopolyMarketBussiness.getMonopolyMarketBackEndGroupList(channelId);
        for (MonopolyMarketBackEndGroup endItem : endGroupList){
            MonopolyMarketCrossGroup crossGroup = crossGroupMap.get(endItem.getGroupId());
            if(crossGroup != null && crossGroup.getFortressState() != endItem.getFortressState()){
                logger.info("边关要塞state 发生变动。groupId:{},原来的FortressState：{}，新的FortressState：{}",crossGroup.getGroupId(),crossGroup.getFortressState(),endItem.getFortressState());
                crossGroup.setFortressState(endItem.getFortressState());
                changeGroupSet.add(crossGroup);
            }
        }
        return changeGroupSet;
    }

    /**
     * 校验后台分组和跨服上的分组是否一致
     * @param channelId
     * @return 返回有变化的分组和新增分组
     */
//    public static Set<MonopolyMarketCrossGroup> checkGroupChange(int channelId){
//        // 与后台校验配置
//        Set<MonopolyMarketCrossGroup> changeGroupSet = new HashSet<>();
//        List<MonopolyMarketBackEndGroup> endGroupList =  MonopolyMarketBussiness.getMonopolyMarketBackEndGroupList(channelId);
//        int now = DateHelper.getCurrentSecond();
//        for (MonopolyMarketBackEndGroup endItem : endGroupList){
//            MonopolyMarketCrossGroup crossGroup = crossGroupMap.get(endItem.getGroupId());
//            if(crossGroup != null){
//                // 校验区服列表是否一致
//                boolean change = false;
//                if(endItem.getState() == 1){
//                    // 跨服分组开启
//                    if(crossGroup.getState() == 1){
//                        // 跨服分组开启->开启  查看分组是否变更
//                        for(Long serverId : endItem.getServerList()){
//                            if(!crossGroup.getServerList().contains(serverId)){
//                                // 新增区服
//                                MonopolyMarketCrossGroup singleServerGroup = getSingleGroupByServerId(channelId,serverId,false);
//                                if(singleServerGroup != null){
//                                    // 关闭独立分组
//                                    singleServerGroup.setState(0);
//                                    singleServerGroup.setChangTime(now);
//                                    changeGroupSet.add(singleServerGroup);
//                                    logger.info("跨服分组新增区服, 关闭独立分组 serverId:{}.",serverId);
//                                }
//                                change = true;
//                            }
//                        }
//                        for(Long serverId : crossGroup.getServerList()){
//                            if(!endItem.getServerList().contains(serverId)){
//                                // 移除分组
//                                MonopolyMarketCrossGroup singleServerGroup = getSingleGroupByServerId(channelId,serverId,false);
//                                if(singleServerGroup != null){
//                                    singleServerGroup.setState(1);
//                                    singleServerGroup.setChangTime(now);
//                                    changeGroupSet.add(singleServerGroup);
//                                    logger.info("跨服分组移除区服, 开启独立分组 serverId:{}.",serverId);
//                                }
//                                change = true;
//                            }
//                        }
//                    }else {
//                        // 跨服分组关闭->开启
//                        changeGroup(channelId,endItem.getServerList(),0, changeGroupSet);
//                        logger.info("开启跨服分组 分组groupId:{} serverList:{}.",endItem.getGroupId(),endItem.getServerList());
//                        change = true;
//                    }
//                }else {
//                    // 关闭
//                    if(crossGroup.getState() == 1){
//                        // 开启->关闭
//                        changeGroup(channelId,crossGroup.getServerList(),1, changeGroupSet);
//                        changeGroup(channelId,endItem.getServerList(),1, changeGroupSet);
//                        change = true;
//                        logger.info("跨服分组关闭, groupId:{}, 开启独立分组信息serverList:{}.",crossGroup.getGroupId(),crossGroup.getServerList());
//                    }else {
//                        // 两边都是 关闭过程中修改分组 不用管
//                    }
//                }
//                if(change){
//                    logger.info("榷场分组变更。后台分组:{},区服分组:{}.",endItem.getServerList(),crossGroup.getServerList());
//                    crossGroup.setState(crossGroup.getState());
//                    crossGroup.setServerList(endItem.getServerList());
//                    crossGroup.setChangTime(DateHelper.getCurrentSecond());
//                    changeGroupSet.add(crossGroup);
//                }
//            }else {
//                crossGroup = creatMonopolyMarketCrossGroup(endItem.getGroupId(),endItem.getChannelId(),endItem.getServerList(),DateHelper.getCurrentSecond(),endItem.getState());
//                if(crossGroup.getState() == 1){
//                    changeGroup(channelId,endItem.getServerList(),0, changeGroupSet);
//                    logger.info("榷场新增分组, 关闭独立分组 serverIdList:{}.",endItem.getServerList());
//                }
//                changeGroupSet.add(crossGroup);
//                logger.info("榷场新增分组。分组id:{},区服:{},state:{}.",endItem.getGroupId(),endItem.getServerList(),endItem.getState());
//            }
//        }
//        return changeGroupSet;
//    }

    /**
     * 创建分组
     * @param groupId
     * @param channelId
     * @param serverList
     * @param changeTime
     * @param state
     * @return
     */
    private static MonopolyMarketCrossGroup creatMonopolyMarketCrossGroup(long groupId, int channelId, List<Long> serverList,int changeTime,int state,int fortressState){
        MonopolyMarketCrossGroup crossGroup = new MonopolyMarketCrossGroup();
        crossGroup.setGroupId(groupId);
        crossGroup.setChannelId(channelId);
        crossGroup.setServerList(serverList);
        crossGroup.setState(state);
        crossGroup.setFortressState(fortressState);
        crossGroup.setChangTime(changeTime);
        crossGroup.setOfficeRefreshTime(changeTime);
        crossGroup.setKingResGrabRefreshTime(changeTime);
        crossGroup.setQueenResGrabRefreshTime(changeTime);
        crossGroup.setFortressRefreshTime(changeTime);
        crossGroup.setInsertOption();
        crossGroupMap.put(crossGroup.getGroupId(),crossGroup);
        return crossGroup;
    }

//    /**
//     * 修改独立分组状态
//     * @param channelId
//     * @param serverList
//     * @param state
//     */
//    private static void changeGroup(int channelId,List<Long> serverList,int state,Set<MonopolyMarketCrossGroup> changeGroupSet){
//        for(Long serverId : serverList){
//            MonopolyMarketCrossGroup item = getSingleGroupByServerId(channelId,serverId,false);
//            if(item != null && item.getState() != state){
//                // 关闭独立分组
//                item.setState(state);
//                item.setChangTime(DateHelper.getCurrentSecond());
//                changeGroupSet.add(item);
//                logger.info("修改独立分组state,  serverId:{}, state:{} .",serverId,state);
//            }
//        }
//    }


    /**
     * 后台的分组 和 跨服维护的分组做比较
     * @param backendGroup
     * @param crossGroup
     * @return
     */
    public static boolean equals(MonopolyMarketBackEndGroup backendGroup, MonopolyMarketCrossGroup crossGroup){
        if(backendGroup.getGroupId() != crossGroup.getGroupId()){
            return false;
        }
        if(backendGroup.getChannelId() != crossGroup.getChannelId()){
            return false;
        }
        if (backendGroup.getServerList().size() != crossGroup.getServerList().size()) {
            return false;
        }
        for (long serverId : backendGroup.getServerList()){
            if(!crossGroup.getServerList().contains(serverId)){
                return false;
            }
        }
        for (long serverId : crossGroup.getServerList()){
            if(!backendGroup.getServerList().contains(serverId)){
                return false;
            }
        }
        if(backendGroup.getState() != crossGroup.getState()){
            return false;
        }
        return true;
    }


    /**
     * 获取区服所在的分组
     * @param serverId
     * @return
     */
    public static MonopolyMarketCrossGroup getOpenGroupByServerId(long serverId){
        MonopolyMarketCrossGroup group = null;
        for(MonopolyMarketCrossGroup item : crossGroupMap.values()){
            if(item.getState() == 1 && item.getServerList().contains(serverId)){
                group = item;
                break;
            }
        }
        return group;
    }

    /**
     * 获取区服所在的分组 （包括未开启的） 优先找开启的
     * @param serverId
     * @return
     */
    public static MonopolyMarketCrossGroup getGroupByServerId(long serverId){
        MonopolyMarketCrossGroup group = null;
        for(MonopolyMarketCrossGroup item : crossGroupMap.values()){
            if(item.getServerList().contains(serverId)){
                group = item;
                if(item.getState() == 1){
                    break;
                }
            }
        }
        return group;
    }


//    /**
//     * 获取区服独立分组
//     * @param serverId
//     * @param newIfNull
//     * @return
//     */
//    private static MonopolyMarketCrossGroup getSingleGroupByServerId(int channelId, long serverId,boolean newIfNull){
//        MonopolyMarketCrossGroup crossGroup = singleCrossGroupMap.get(serverId);
//        if(crossGroup == null && newIfNull){
//            crossGroup = new MonopolyMarketCrossGroup();
//            crossGroup.setInsertOption();
//            crossGroup.setChannelId(channelId);
//            crossGroup.setGroupId((int)serverId);
//            List<Long> serverList = new ArrayList<>();
//            serverList.add(serverId);
//            crossGroup.setServerList(serverList);
//            // 默认开启
//            crossGroup.setState(1);
//            crossGroup.setChangTime(DateHelper.getCurrentSecond());
//            singleCrossGroupMap.put(crossGroup.getGroupId(),crossGroup);
//            logger.info("榷场新增独立分组。分组id:{},区服:{}.",serverId,serverList);
//        }
//        return crossGroup;
//    }


    /**
     * 同步下发跨服分组
     * @param serverId
     */
    public static void synMonopolyMarketCrossGroup(long serverId){
        MonopolyMarketProto.MonopolyMarketSynCrossGroupToGameServerMsg.Builder synCrossGroup = MonopolyMarketProto.MonopolyMarketSynCrossGroupToGameServerMsg.newBuilder();
        MonopolyMarketCrossGroup crossGroup = MonopolyMarketCrossGroupMgr.getGroupByServerId(serverId);
        if(crossGroup != null){
            MonopolyMarketProto.MonopolyMarketCrossGroupEntity.Builder crossGroupBuilder = MonopolyMarketProto.MonopolyMarketCrossGroupEntity.newBuilder();
            crossGroupBuilder.setChannelId(crossGroup.getChannelId());
            crossGroupBuilder.setGroupId(crossGroup.getGroupId());
            crossGroupBuilder.addAllServerList(crossGroup.getServerList());
            crossGroupBuilder.setChangTime(crossGroup.getChangTime());
            crossGroupBuilder.setOfficeCfgChangTime(crossGroup.getOfficeCfgChangTime());
            crossGroupBuilder.setKingCfgChangTime(crossGroup.getKingCfgChangTime());
            crossGroupBuilder.setQueenCfgChangTime(crossGroup.getQueenCfgChangTime());
            crossGroupBuilder.setState(crossGroup.getState());
            crossGroupBuilder.setFortressState(crossGroup.getFortressState());
            synCrossGroup.setCrossGroup(crossGroupBuilder);
            MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(GameProtocol.S_MONOPOLY_MARKET_SYN_CROSS_GROUP, synCrossGroup));
        }
    }
}
